<?php
/**
 * DBShop 电子商务系统
 *
 * ==========================================================================
 * @link      https://www.dbshop.net/
 * @copyright 北京珑大钜商科技有限公司，并保留所有权利。
 * @license   https://www.dbshop.net/license.html License
 * ==========================================================================
 *
 * @author    静静的风 <baron@loongdom.cn>
 *
 */

namespace User\Service\Common\AppLogin;

use Admin\Data\Common;
use Laminas\Session\Container;

include 'vendor/alipay/aop/AopClient.php';
include 'vendor/alipay/aop/request/AlipaySystemOauthTokenRequest.php';
include 'vendor/alipay/aop/request/AlipayUserInfoShareRequest.php';

class AlipayLogin
{
    public $redirectUri;

    private $gatewayUrl = 'https://openapi.alipay.com/gateway.do';
    private $authUrl    = 'https://openauth.alipay.com/oauth2/publicAppAuthorize.htm?';
    private $format     = 'json';
    private $charset    = 'UTF-8';
    private $signType   = 'RSA2';
    private $aopClient;
    private $loginSession;
    private $customerConfig = [];

    public function __construct()
    {
        $this->customerConfig   = Common::readConfigFile('customer');
        $this->loginSession     = new Container('alipaySession');

        $this->aopClient = new \AopClient();
        $this->aopClient->gatewayUrl        = $this->gatewayUrl;
        $this->aopClient->appId             = $this->customerConfig['alipay_app_id'];
        $this->aopClient->rsaPrivateKey     = $this->customerConfig['alipay_private_key'];
        $this->aopClient->alipayrsaPublicKey= $this->customerConfig['alipay_public_key'];
        $this->aopClient->format            = $this->format;
        $this->aopClient->postCharset       = $this->charset;
        $this->aopClient->signType          = $this->signType;
    }

    public function toLogin()
    {
        $state = md5(uniqid(rand(), TRUE));

        $this->authUrl .= 'app_id='.$this->customerConfig['alipay_app_id'];
        $this->authUrl .= '&scope=auth_user';
        $this->authUrl .= '&redirect_uri=' . urlencode($this->redirectUri);
        $this->authUrl .= '&state='.$state;//这里可自定义

        $this->loginSession->offsetSet('alipayState', $state);

        @header("Location: " . $this->authUrl);
        exit();
    }

    /**
     * 跳转返回处理
     */
    public function loginCallBock()
    {
        if ($this->loginSession->offsetGet('alipayState') != $_REQUEST['state']) {
            exit('<h2>The state does not match. You may be a victim of CSRF.</h2>');
        }
        $authCode = $_REQUEST['auth_code'];
        $request = new \AlipaySystemOauthTokenRequest();
        $request->setCode($authCode);
        $request->setGrantType("authorization_code");

        $result = $this->aopClient->execute($request);
        $responseNode   = str_replace(".", "_", $request->getApiMethodName()) . "_response";
        $accessToken     = $result->$responseNode->access_token;
        if(!empty($accessToken)) {
            $userRequest = new \AlipayUserInfoShareRequest();
            $userResult  = $this->aopClient->execute($userRequest, $result->$responseNode->access_token);
            $userResponseNode   = str_replace(".", "_", $userRequest->getApiMethodName()) . "_response";
            $userResultCode     = $userResult->$userResponseNode->code;
            if(!empty($userResultCode) && $userResultCode == 10000) {
                $this->loginSession->offsetSet('alipayUserName',    $userResult->$userResponseNode->nick_name);
                $this->loginSession->offsetSet('alipayOpenId',      $userResult->$userResponseNode->user_id);
            } else exit($userResult->$responseNode->msg);

        } else exit($result->$responseNode->msg);
    }

    /**
     * openId
     * @return mixed|null
     */
    public function openId()
    {
        return $this->loginSession->offsetGet('alipayOpenId');
    }

    /**
     * unionId
     * @return mixed|null
     */
    public function unionId()
    {
        return '';
    }

    /**
     * 账户信息
     * @return mixed
     */
    public function loginUserInfo()
    {
        return ['nickname' => $this->loginSession->offsetGet('alipayUserName')];
    }

    /**
     * 清除使用过的session
     */
    public function clearOtherLoginSession()
    {
        $this->loginSession->getManager()->getStorage()->clear($this->loginSession->getName());
    }
}